package com.dongnam.quanly.common.util;

import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.util.StringTokenizer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class StringUtil {

	private static final Logger logger = LoggerFactory.getLogger(StringUtil.class);

	// private static BigDecimal TWO_TO_64 = new
	// BigDecimal(Long.MAX_VALUE).subtract(new
	// BigDecimal(Long.MIN_VALUE)).add(new BigDecimal(1));
	private static BigDecimal TWO_TO_64 = new BigDecimal(2).pow(64);

	public static boolean isEmpty(String param) {
		if ((param == null) || (param.length() == 0)) {
			return true;
		}
		return false;
	}

	public static boolean isWhitespace(String param) {
		if (param == null) {
			return true;
		}

		return isEmpty(param.trim());
	}

	public static boolean isInteger(String param) {
		try {
			Integer.parseInt(param);
			return true;
		} catch (NumberFormatException e) {
			return false;
		}
	}

	public static String nullSubstitute(String param) {
		return (param == null) ? "" : param;
	}

	public static String getHexString(byte[] inData) {
		String ret_val = "";
		for (int j = 0; j < inData.length; j++) {
			int tmp_len = Integer.toHexString(inData[j]).toUpperCase().length();
			if (tmp_len >= 2) {
				ret_val = ret_val + Integer.toHexString(inData[j]).toUpperCase().substring(tmp_len - 2) + " ";
			} else {
				ret_val = ret_val + "0" + Integer.toHexString(inData[j]).toUpperCase() + " ";
			}
		}
		return ret_val;
	}

	public static String getHexString(byte[] inData, int dataLen) {
		String ret_val = "";
		for (int j = 0; j < dataLen; j++) {
			int tmp_len = Integer.toHexString(inData[j]).toUpperCase().length();
			if (tmp_len >= 2) {
				ret_val = ret_val + Integer.toHexString(inData[j]).toUpperCase().substring(tmp_len - 2) + " ";
			} else {
				ret_val = ret_val + "0" + Integer.toHexString(inData[j]).toUpperCase() + " ";
			}
		}
		return ret_val;
	}

	public static String getHexString(ByteBuffer buffer) {
		String ret_val = "";
		while (buffer.hasRemaining()) {
			String val = Integer.toHexString(buffer.get() & 0x00FF).toUpperCase();
			int len = val.length();
			if (len < 2) {
				ret_val += "0";
			}
			ret_val += val + " ";
		}
		return ret_val;
	}

	public static byte[] getBytesfromHexString(String hexstring) {
		StringTokenizer st = new StringTokenizer(hexstring, " ");
		byte[] byteArr = new byte[st.countTokens()];
		int index = 0;
		while (st.hasMoreTokens()) {
			byteArr[index] = (byte) (Integer.parseInt(st.nextToken(), 16) & 0x000000FF);
			index++;
		}
		return byteArr;
	}

	public static String convertToString(int[][] values, String majorDelimiter, String minorDelimiter) {
		String ret = "";
		for (int i = 0; i < values.length; i++) {
			if (i != 0) {
				ret += majorDelimiter;
			}
			for (int j = 0; j < values[i].length; j++) {
				if (j != 0) {
					ret += minorDelimiter;
				}
				ret += values[i][j];
			}
		}
		return ret;
	}

	public static String convertToString(String[] values, String delimiter) {
		StringBuilder builder = new StringBuilder(16 * values.length);
		if (values.length > 0) {
			builder.append(values[0]);
			for (int i = 1; i < values.length; i++) {
				builder.append(delimiter);
				builder.append(values[i]);
			}
		}
		return builder.toString();
	}

	public static String convertToString(Object[] values, String delimiter) {
		StringBuilder builder = new StringBuilder(16 * values.length);
		if (values.length > 0) {
			builder.append(values[0]);
			for (int i = 1; i < values.length; i++) {
				builder.append(delimiter);
				builder.append(values[i]);
			}
		}
		return builder.toString();
	}

	public static String convertToString(int[] values, String delimiter) {
		String ret = "";
		for (int i = 0; i < values.length; i++) {
			if (i != 0) {
				ret += delimiter;
			}
			ret += values[i];
		}
		return ret;
	}

	public static int[][] split2DIntList(String str, String majorDelimiter, String minorDelimiter) {
		int[][] ret;
		String[] strList = str.split(majorDelimiter);
		if (strList.length == 0) {
			ret = new int[0][0];
		} else {
			ret = new int[strList.length][];
			for (int i = 0; i < strList.length; i++) {
				String[] subStrList = strList[i].split(minorDelimiter);
				if (subStrList.length == 0) {
					ret[i] = new int[0];
				} else {
					ret[i] = new int[subStrList.length];
					for (int j = 0; j < subStrList.length; j++) {
						ret[i][j] = Integer.parseInt(subStrList[j]);
					}
				}
			}
		}
		return ret;
	}

	public static int[] splitIntList(String str, String delimiter) {
		int[] ret;
		String[] strList = str.split(delimiter);
		if (strList.length == 0) {
			ret = new int[0];
		} else {
			ret = new int[strList.length];
			for (int i = 0; i < strList.length; i++) {
				ret[i] = Integer.parseInt(strList[i]);
			}
		}
		return ret;
	}

	public static boolean contains(String keywords, String target) {
		boolean ok = true;
		String[] params = keywords.trim().toLowerCase().split(" ");
		String copy = target.trim().toLowerCase();
		// logger.debug("target after process={}",target);
		for (int i = 0; i < params.length; i++) {
			String param = params[i].trim();
			// logger.debug("param after process={}",param);
			ok = ok && copy.contains(param);
			if (copy.contains(param)) {
				ok = ok && true;
				logger.debug("target {} contains {}", target, param);
			} else {
				ok = false;
			}
		}
		if (ok)
			logger.debug("keywords={}, target={}, ok={}", keywords, target, ok);
		return ok;
	}

	public static String unsignedLongToString(long value) {
		if (value < 0) {
			// -1 Long => 0xFFFFFFFF FFFFFFFF
			// 2^64 + (input)
			BigDecimal longInput = new BigDecimal(value);
			BigDecimal longOutput = TWO_TO_64.add(longInput);
			return longOutput.toString();
		} else {
			return String.valueOf(value);
		}
	}

}
